<!-- 
使用方法：
 <cy-scroll-view style="height: 100%" :pageNum="paging.pageNum" :pageSize="paging.pageSize" :total="paging.total" @load="getData">
 xxxxxxxxx
 </cy-scroll-view>
 注：
 1.改组件的父节点需要有固定高度，父节点最好不要设置flex布局，不然会让宽度不能100%，如果一定要设置，在调用时加上style="width:100%"
 2.微信小程序会自动在组件外面包一层<components/CyScrollView/index>，所以需要再使用的时候，设置style="height:100%"
 3.如果需要初始时显示加载中，total设置为-1
 4.使用try finally包裹父组件的getData方法，并在finally中执行,scrollRef.value.loadEnd()方法，通知滚动组件加载完成
 -->
<template>
	<view class="cy-scroll-view">
		<scroll-view
			:scroll-y="true"
			enable-flex
			class="scroll-Y"
			:refresher-enabled="load ? true : false"
			:refresher-triggered="refresherTriggered"
			:refresher-threshold="100"
			refresher-background="#fff"
			:scrollTop="scrollTop"
			@scrolltolower="scrolltolower"
			@refresherrefresh="onRefresh"
			@scroll="scroll">
			<view class="scroll-list">
				<slot></slot>
			</view>
			
			<block v-if="pageNum !== -1">
				<view v-if="total==0" class="t-empty">
					 <cy-empty :text="emptyText" />
				</view>
				<view v-else class="load-state">
					<up-loadmore v-if="total == -1 || loading" status="loading" />
					<view v-else-if="noMore" class="tips">没有更多数据啦~</view>
				</view>
			</block>
			
			<view v-if="safeBottom" class="safe-area-inset-bottom" :style="{'--safe-bottom': safeBottom}"></view>
		</scroll-view>
	</view>
</template>

<script setup>
import { ref, watch, nextTick, computed, onMounted } from 'vue'	

const emits = defineEmits(['scroll'])
const props = defineProps({
	// 是否开启下拉刷新
	refresh: {
		type: Boolean,
		default: true,
	},
	// 加载中
	loading: {
		type: Boolean,
		default: false
	},
	// 默认-1表示不使用分页
	pageNum: {
		type: Number,
		default: -1
	},
	pageSize: {
		type: Number
	},
	total: {
		type: Number
	},
	load: {
		type: [Function, null],
		default: () => (null)
	},
	emptyText: {
		type: String,
		default: '暂无数据'
	},
	// 安全距离 最小距离，苹果使用env(safe-area-inset-bottom)，不是苹果使用safeBootom
	safeBottom: {
		type: String,
		default: ''
	}
})
const lock = ref(false);
const triggered = ref(false);
const refresherTriggered = ref(false);
const scrollTop = ref(0);

watch([() => props.loading, () => triggered.value], () => {
	if(!refresherTriggered.value) {
		if(triggered.value) {
			refresherTriggered.value = true;
		}
	} else {
		if(!triggered.value && !props.loading) {
			refresherTriggered.value = false;
		}
	}
})

const noMore = computed(() => {
	let res = false;
	if(props.pageNum !== -1) {
		res = props.total <= 0 || (props.pageNum+1) > Math.ceil(props.total / props.pageSize);
	}
	return res;
})

onMounted(() => {
	
})

const scrolltolower = () => {
	if(props.pageNum === -1) {
		return;
	}

	if(props.loading || noMore.value) {
		return;
	}

	if(lock.value) {
		return;
	}
	lock.value = true;

	props.load();

	setTimeout(() => {
		lock.value = false;
	}, 100);
}

var refreshTimer = null;
const onRefresh = () => {
	if(props.loading) {
		console.error('还在加载中');
		return;
	}
	// 显示下拉刷新
	triggered.value = true;
	props.load(true);

	setTimeout(() => {
		triggered.value = false;
	}, 200);
	
	// 5s后强制关闭下拉动画
	clearTimeout(refreshTimer);
	refreshTimer = setTimeout(() => {
		refresherTriggered.value = false;
	}, 5000);
}

// let timer = null;
const scroll = (e) => {
	emits('scroll', e);
	// clearTimeout(timer);
	// timer = setTimeout(() => {
	// 	scrollTop.value = e.detail.scrollTop;
	// 	console.log(scrollTop.value);
	// }, 1000);
}

const setScrollTop = (val) => {
	if(scrollTop.value == val) {
		scrollTop.value = val-1;
		setTimeout(() => {
			scrollTop.value = val;
		}, 30);
	} else {
		scrollTop.value = val;
	}
}

defineExpose({
	setScrollTop
})
</script>

<style lang="scss" scoped>
.cy-scroll-view {
	height: 100%;
	width: 100%;
	.scroll-Y {
		height: 100%;
		.load-state {
			padding: 20rpx 0;
		}
		.t-empty {
			padding-top: 60rpx;
			padding-bottom: 40rpx;
		}
		.tips {
			text-align: center;
		}
		
		.safe-area-inset-bottom {
			height: max(calc(var(--safe-bottom) - 20rpx), calc(env(safe-area-inset-bottom) - 20rpx));
			width: 100%;
		}
	}
}	
</style>